/*
 * ringlist.hpp
 *
 *  Created on: 2017年8月1日
 *      Author: work
 */

#ifndef _DM_RINGLIST_HPP_
#define _DM_RINGLIST_HPP_

namespace dm{

template<typename T>
class TRingList{
	TRingList( const TRingList& );
	TRingList& operator=( const TRingList& );
public:
	struct SNode{
		SNode* pre;
		SNode* nxt;
		T e;
	};

	TRingList():m_cur(0){
	}

	bool isRing()const{
		if( m_cur==0 )
			return false;

		SNode* p = m_cur->nxt;
		while( p!=m_cur ){
			if( p==0 )
				return false;
			p = p->nxt;
		}

		return true;
	}

	void append( const T& e ){
		if( m_cur==0 ){
			m_cur = new SNode;
			m_cur->pre = 0;
			m_cur->nxt = 0;
			m_cur->e = e;
		}else{
			if( m_cur->e == e ){
			}
			SNode* n = new SNode;
			n->pre = m_cur;
			n->nxt = 0;
			n->e = e;

			SNode* p = m_cur->pre;
			while( p!=0 ){
				if( p->e==e ){

				}
			}

		}
	}

	int size()const{
		int s = 0;

		if( m_cur==0 )
			return s;

		++s;

		const SNode* p = m_cur->pre;
		while( p!=0 ){
			++s;
			p = p->pre;
			if( p==m_cur )
				break;
		}

		p = m_cur->nxt;
		while( p!=0 ){
			++s;
			p = p->nxt;
			if( p==m_cur )
				break;
		}

		return s;
	}

	inline bool cur( T& e )const{
		if( m_cur==0 )
			return false;
		e = m_cur->e;
		return true;
	}

	inline bool pre( T& e )const{
		if( m_cur==0 || m_cur->pre==0 )
			return false;
		e = m_cur->pre->e;
		return true;
	}

	inline bool nxt( T& e )const{
		if( m_cur==0 || m_cur->nxt==0 )
			return false;
		e = m_cur->nxt->e;
		return true;
	}

	bool movePre(){
		if( m_cur==0 || m_cur->pre==0 )
			return false;
		m_cur = m_cur->pre;
		return true;
	}

	bool moveNxt(){
		if( m_cur==0 || m_cur->nxt==0 )
			return false;
		m_cur = m_cur->nxt;
		return true;
	}

	bool contain( const T& e )const{
		if( m_cur==0 )
			return false;

		if( m_cur->e==e )
			return true;

		const SNode* p = m_cur->pre;
		while( p!=0 ){
			if( p->e==e )
				return true;
			p = p->pre;
			if( p==m_cur )
				return false;
		}

		p = m_cur->nxt;
		while( p!=0 ){
			if( p->e==e )
				return true;
			p = p->nxt;
		}

		return false;
	}

	SNode* find( const T& e ){
		if( m_cur==0 )
			return 0;

		if( m_cur->e==e )
			return m_cur;

		SNode* p = m_cur->pre;
		while( p!=0 ){
			if( p->e==e )
				return p;
			p = p->pre;
			if( p==m_cur )
				return 0;
		}

		p = m_cur->nxt;
		while( p!=0 ){
			if( p->e==e )
				return p;
			p = p->nxt;
		}

		return 0;
	}

	const SNode* find( const T& e )const{
		if( m_cur==0 )
			return 0;

		if( m_cur->e==e )
			return m_cur;

		const SNode* p = m_cur->pre;
		while( p!=0 ){
			if( p->e==e )
				return p;
			p = p->pre;
			if( p==m_cur )
				return 0;
		}

		p = m_cur->nxt;
		while( p!=0 ){
			if( p->e==e )
				return p;
			p = p->nxt;
		}

		return 0;
	}

private:
	SNode* m_cur;
};

}

#endif /* INCLUDE_DM_RINGLIST_HPP_ */
